package com.icbc.common.fileupload;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.Map;

import javax.sql.DataSource;

import oracle.sql.BLOB;

import com.icbc.ctp.channel.IChannelHandler;
import com.icbc.ctp.channel.IChannelRequest;
import com.icbc.ctp.channel.IChannelResponse;
import com.icbc.ctp.channel.commons.MultipartChannelRequest;
import com.icbc.ctp.channel.commons.MultipartFile;
import com.icbc.ctp.channel.flow.exceptions.HandlerException;
import com.icbc.ctp.core.IChannelContext;
import com.icbc.ctp.core.exception.ContextEvaluateException;
import com.icbc.ctp.ioc.ConstructorException;
import com.icbc.ctp.ioc.FactortInitialException;
import com.icbc.ctp.ioc.ModulesException;
import com.icbc.ctp.ioc.xmlconfig.FileSystemXmlApplicationContext;
import com.icbc.common.fileupload.DateUtil;
import com.icbc.common.fileupload.FileUtil;
import com.icbc.common.fileupload.IdUtil;

/**
 * 上传处理类
 * httpFlag 是否需要http方式访问 1是 0否
 * saveType 保存方式1 以附件方式保存 0以数据库方式保存
 * **/
public class PubFileSaveHandler implements IChannelHandler {
	
  private static final String HANDLER_NAME = "文件上传处理类";
  
  private String uploadPath;
  
  private String httpuploadPath;

  @SuppressWarnings("unchecked")
  public void handleRequest(IChannelRequest request,IChannelResponse response) throws HandlerException {
				
		MultipartChannelRequest httpRequest = (MultipartChannelRequest) request;
		Connection conn = null;
		String fileId = "";
		try {
			IChannelContext channelContext = httpRequest.getChannelContext();
			
			//是否需要http方式访问,比如头像,是需要给出http连接的 1是 0否
			String httpFlag = channelContext.getData().get("httpFlag")==null ? "0" : (String)channelContext.getData().get("httpFlag");
			
			//保存类型 1为附件保存 2为数据库保存
			String saveType = channelContext.getData().get("saveType")==null ? "1" : (String)channelContext.getData().get("saveType");
			
			DataSource basicDS = (DataSource) FileSystemXmlApplicationContext.get("ORACLEJDBC");
			conn = basicDS.getConnection();
			conn.setAutoCommit(false);
			
			Map fileMap = httpRequest.getFileMap();
			for (Object entry : fileMap.keySet()) {
				MultipartFile fileItem = (MultipartFile) fileMap.get(entry);
				if ((fileItem == null) || (fileItem.isEmpty())) {
					continue;
				}
				if(saveType.equals("2")){
					fileId = writeFileToBLob(conn, fileItem);
				}else{
					try {
						fileId = writeFileToFile(conn, fileItem,httpFlag);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				channelContext.setValueAt("fileId", fileId);
			}
		} catch (ModulesException e2) {
			e2.printStackTrace();
		} catch (FactortInitialException e2) {
			e2.printStackTrace();
		} catch (ConstructorException e2) {
			e2.printStackTrace();
		} catch (SQLException e) {
			try {
				conn.rollback();
				conn.close();
			} catch (SQLException e2) {
				e2.printStackTrace();
			}
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ContextEvaluateException e) {
			e.printStackTrace();
		}finally{
			try {
				if(conn!=null){
					conn.commit();
					conn.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}

	@SuppressWarnings("deprecation")
	public String writeFileToBLob(Connection conn, MultipartFile fileItem)
			throws SQLException, HandlerException, IOException {
		String sqlStr2 = "INSERT INTO CFS_FILE_INFO(" +
						 "FILE_ID,FILE_NAME,FILE_TYPE,UPLOAD_TIME,UPLOAD_USER,SAVE_TYPE,FILE_CONTENT,FILE_PATH) " +
						 "VALUES(?,?,?,sysdate,?,?,empty_blob(),?)";
		
		String sqlStr3 = "select FILECONTENT from foms_file t where t.fileid = ? for update";
		PreparedStatement stmt = null;
		ResultSet result = null;
		OutputStream os = null;
		InputStream is = null;
		
		String fullFileName = fileItem.getFileItem().getName();
		
		String fileName = FileUtil.getFileName(fullFileName);
		
		String fileType = FileUtil.getFileExt(fullFileName);
		
		String fileid = IdUtil.getRandomStr();
		
		stmt = conn.prepareStatement(sqlStr2);
		stmt.setString(1, fileid);
		stmt.setString(2, fileName);
		stmt.setString(3, fileType);
		stmt.setString(4, "");//POST_USER
		stmt.setString(5, "2");//SAVE_TYPE
		stmt.setString(6, "");//FILE_PATH
		stmt.executeUpdate();
		
		// 存储blob
		stmt = conn.prepareStatement(sqlStr3);
		stmt.setString(1, fileid);
		result = stmt.executeQuery();
		BLOB out_blob = null;
		if (result.next()) {
			out_blob = (BLOB) result.getObject(1);
		}
		os = out_blob.getBinaryOutputStream();
		is = fileItem.getInputStream();
		byte[] b = new byte[is.available()];   
		is.read(b);
		os.write(b);
		is.close();
		os.close();
		result.close();
		stmt.close();

		return fileid;
	}
	
	public String writeFileToFile(Connection conn, MultipartFile fileItem,String httpFlag) throws Exception{
		String fileid = IdUtil.getRandomStr();
		
		String file_save_path = "";
		if(httpFlag.equals("1")){
			file_save_path = FileSystemXmlApplicationContext.getFactory().getPropertyConfigurer().getPros().getProperty("WEB_ROOT")+"/"+this.getHttpuploadPath();
		}else{
			file_save_path = this.getUploadPath();
		}
		
		String datePath = DateUtil.toStr(new Date(), "yyyy/MM/dd");
		
		String realFileDir = file_save_path+"/"+datePath;
		
		FileUtil.createDir(realFileDir);
		
		String fullFileName = fileItem.getFileItem().getName();
		
		String fileName = FileUtil.getFileName(fullFileName);
		
		String fileType = FileUtil.getFileExt(fullFileName);
		
		String realFilePath = realFileDir+"/"+fileid+"."+fileType;
		
		fileItem.getFileItem().write(new File(realFilePath));
		
		String relativePath = this.getHttpuploadPath()+"/"+datePath+"/"+fileid+"."+fileType;
		
		String sqlStr2 = "INSERT INTO CFS_FILE_INFO(" +
 						 "FILE_ID,FILE_NAME,FILE_TYPE,UPLOAD_USER,SAVE_TYPE,FILE_PATH,HTTP_PATH,UPLOAD_TIME) " +
						 "VALUES(?,?,?,?,?,?,?,sysdate)";
		
		PreparedStatement stmt = null;
		
		stmt = conn.prepareStatement(sqlStr2);
		stmt.setString(1, fileid);
		stmt.setString(2, fileName);
		stmt.setString(3, fileType);
		stmt.setString(4, "");//POST_USER
		stmt.setString(5, "1");//SAVE_TYPE
		
		/*if(httpFlag.equals("1")){//如果需要http访问,保存相对路径
			stmt.setString(6, relativePath);//FILE_PATH
		}else{
			stmt.setString(6, realFilePath);//FILE_PATH
		}*/
		stmt.setString(6, realFilePath);//FILE_PATH
		stmt.setString(7, relativePath);//FILE_PATH
		
		//添加上传日期
		//stmt.setString(7, DateUtil.toStr(new Date(),"yyyy-MM-dd"));
		
		stmt.executeUpdate();
		
		stmt.close();
		
		return fileid;
	}
  
  public String getHandlerName() {
    return HANDLER_NAME;
  }

	public String getUploadPath() {
		return uploadPath;
	}
	
	public void setUploadPath(String uploadPath) {
		this.uploadPath = uploadPath;
	}

	public String getHttpuploadPath() {
		return httpuploadPath;
	}

	public void setHttpuploadPath(String httpuploadPath) {
		this.httpuploadPath = httpuploadPath;
	}
  
}
